/*
 * @Author: 黑白灰01 3193273703@qq.com
 * @Date: 2025-09-01 14:34:54
 * @LastEditors: 黑白灰01 3193273703@qq.com
 * @LastEditTime: 2025-09-01 14:36:19
 * @FilePath: /hei-oa/src/common/filters/http-exception.filter.ts
 * @Description: 异常过滤器
 */
// src/common/filters/http-exception.filter.ts
import {
    ExceptionFilter,
    Catch,
    ArgumentsHost,
    HttpException,
    HttpStatus,
  } from '@nestjs/common';
  import { Request, Response } from 'express';
  import { BaseResponse } from '../response/base-response.dto';
  import { RESPONSE_CODE, RESPONSE_MSG } from 'src/common/enums/code';
  
  @Catch()
  export class HttpExceptionFilter implements ExceptionFilter {
    catch(exception: any, host: ArgumentsHost) {
      const ctx = host.switchToHttp();
      const response = ctx.getResponse<Response>();
      const request = ctx.getRequest<Request>();
  
      let status = HttpStatus.INTERNAL_SERVER_ERROR;
      let message: string = RESPONSE_MSG.FAILURE; // 显式声明为 string 类型
      let code = RESPONSE_CODE.INTERNAL_SERVER_ERROR;
      
      if (exception instanceof HttpException) {
        status = exception.getStatus();
        const response = exception.getResponse() as any;
        message = typeof response === 'string' 
          ? response 
          : response.message || response.error;
        
        code = this.mapHttpStatusToResponseCode(status);
      } else if (exception instanceof Error) {
        message = exception.message;
      }
  
      // 开发模式显示完整错误堆栈
      const env = process.env.NODE_ENV;
      if (env !== 'production') {
        console.error(exception);
      }
  
      response
        .status(status)
        .json(BaseResponse.error(code, message, request.url));
    }
  
    private mapHttpStatusToResponseCode(status: number): RESPONSE_CODE {
      switch (status) {
        case HttpStatus.BAD_REQUEST:
          return RESPONSE_CODE.BAD_REQUEST;
        case HttpStatus.UNAUTHORIZED:
          return RESPONSE_CODE.UNAUTHORIZED;
        case HttpStatus.FORBIDDEN:
          return RESPONSE_CODE.FORBIDDEN;
        case HttpStatus.NOT_FOUND:
          return RESPONSE_CODE.NOT_FOUND;
        default:
          return RESPONSE_CODE.INTERNAL_SERVER_ERROR;
      }
    }
  }